package my.edu.model.bills.pendingBills.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import my.edu.constant.BillsType;
import my.edu.model.bills.bound.service.IAssemblyOrderService;
import my.edu.model.bills.bound.service.IDisassemblyOrderService;
import my.edu.model.bills.bound.service.IOtherInboundOrderService;
import my.edu.model.bills.bound.service.IOtherOutboundOrderService;
import my.edu.model.bills.fund.service.IOtherExpenseOrderService;
import my.edu.model.bills.fund.service.IOtherIncomeOrderService;
import my.edu.model.bills.fund.service.IPreReceiptOrderService;
import my.edu.model.bills.fund.service.IReceiptOrderService;
import my.edu.model.bills.pendingBills.PendingBills;
import my.edu.model.bills.pendingBills.mapper.PendingBillsMapper;
import my.edu.model.bills.pendingBills.PendingBills;
import my.edu.model.bills.pendingBills.mapper.PendingBillsMapper;
import my.edu.model.bills.purchase.service.IPurchaseOrderService;
import my.edu.model.bills.purchase.service.IPurchaseReturnOrderService;
import my.edu.model.bills.sales.service.ILogisticsServiceService;
import my.edu.model.bills.sales.service.ISalesOrderService;
import my.edu.model.bills.sales.service.ISalesReturnOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Service
public class PendingBillsServiceImpl extends ServiceImpl<PendingBillsMapper, PendingBills> implements IPendingBillsService {

    @Autowired
    private BillsType billsType;

    @Override
    public Map<String, List> getPendingBills() {
        //创建结果双列集合
        Map<String, List> res = new HashMap<>();
        //查询所有待审核单据
        List<PendingBills> list = list();
        //解析有哪些类型的单据，并且去重，将单据id保存到list中
        Map<String, List<Long>> typeMap = list.stream()
                .collect(Collectors.groupingBy(
                        PendingBills::getBillType,
                        Collectors.mapping(PendingBills::getBillId, Collectors.toList())
                ));
        //获取对应单据详情
        if (!typeMap.isEmpty()) {
            // 使用CompletableFuture来实现多线程并发查询单据详情
            List<CompletableFuture<Void>> futures = typeMap.entrySet().stream()
                    .map(i -> fetchBillsDetails(i.getKey(), i.getValue(), res))
                    .toList();
            // 等待所有的CompletableFuture任务完成
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        }
        return res;
    }

    @Async
    protected CompletableFuture<Void> fetchBillsDetails(String i, List<Long> j, Map<String, List> res) {
        Object b = billsType.getBillsTypeService(i);
        if (b instanceof IPurchaseOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof IPurchaseReturnOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof ISalesOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof ISalesReturnOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof IOtherInboundOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof IOtherOutboundOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof IOtherIncomeOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof IOtherExpenseOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof IReceiptOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof IPreReceiptOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof IAssemblyOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof IDisassemblyOrderService c) res.put(i, c.listByIds(j));
        else if (b instanceof ILogisticsServiceService c) res.put(i, c.listByIds(j));
        else throw new IllegalArgumentException("Unknown type: " + i);
        return CompletableFuture.completedFuture(null);
    }
}
